import { CreateHandleTo, IHandle, RemoveHandle } from "../data/data-handle";


/**
 * 状态管理
 * @param state 状态名称集合
 */
class State {

    private _state: Array<string | number>;
    private _changeHandles: IHandle<Array<string | number>>[] = [];

    constructor(...state: Array<string | number>) {
        this._state = [...state];
    }

    /**
     * 添加状态改变时的回调函数对象
     * @param func 回调函数
     * @returns 回调函数对象
     */
    public onChange(func: { (added: Array<string | number>, removed: Array<string | number>): void }): IHandle<Array<string | number>> {
        return CreateHandleTo(func, this._changeHandles);
    }

    /**
     * 移除状态改变时的回调函数对象
     * @param handle 回调函数对象或其id
     */
    public removeChangeHandle(handle: number | IHandle<Array<string | number>>): void {
        RemoveHandle(handle, this._changeHandles);
    }

    /**
     * 获取所有状态
     */
    public get stats() {
        return this._state;
    }

    /**
     * 检测给定的状态是否都存在
     * @param stats 目标状态集合
     * @returns 是否都存在
     */
    public exist(...stats: Array<string | number>): boolean {
        for (const st of stats) {
            const index = this._state.indexOf(st);
            if (index === -1) return false;
        }
        return true;
    }

    /**
     * 检测给定的状态中是否有至少一个存在
     * @param stats 目标状态集合
     * @returns 是否至少有一个存在
     */
    public anyExist(...stats: Array<string | number>): boolean {
        for (const st of stats) {
            const index = this._state.indexOf(st);
            if (index !== -1) return true;
        }
        return false;
    }

    /**
     * 检测给定的状态是否都不存在
     * @param stats 目标状态集合
     * @returns 是否都不存在
     */
    public notExist(...stats: Array<string | number>): boolean {
        for (const st of stats) {
            const index = this._state.indexOf(st);
            if (index !== -1) return false;
        }
        return true;
    }

    /**
     * 检测给定的状态是否至少有一个不存在
     * @param stats 目标状态集合
     * @returns 是否至少有一个不存在
     */
    public anyNotExist(...stats: Array<string | number>): boolean {
        for (const st of stats) {
            const index = this._state.indexOf(st);
            if (index === -1) return true;
        }
        return false;
    }

    /**
     * 添加状态
     * @param stats 要添加的状态
     */
    public add(...stats: Array<string | number>): void {
        const changed: Array<string | number> = [];
        for (const st of stats) {
            if (!this._state.includes(st)) {
                this._state.push(st);
                changed.push(st);
            }
        }
        this._changeHandles.forEach(handle => handle.callback(changed, []));
    }

    /**
     * 移除状态
     * @param stats 要移除的状态
     */
    public remove(...stats: Array<string | number>): void {
        const changed: Array<string | number> = [];
        for (const st of stats) {
            const index = this._state.indexOf(st);
            if (index === -1) continue;
            this._state.splice(index, 1);
            changed.push(st);
        }
        this._changeHandles.forEach(handle => handle.callback([], changed));
    }

    /**
     * 清除状态
     */
    public clear(): void {
        const changed = [...this._state];
        this._state = [];
        this._changeHandles.forEach(handle => handle.callback([], changed));
    }
}

export { State };